#include <iostream>
using namespace std;
//这是一个对于无向图的Prim算法，并且判断了图是否连通。
#define INF 0x7fffffff
int map[5001][5001];
int lowcost[5001];
int n;
int m;

int prim(int n){
    int ans=0;  //记录最小权值和
    //int closest[n] = {};    用来记录最小生成树怎么生成的

    for(int i=0;i<n;++i){
        lowcost[i] = map[0][i];
    }
    lowcost[0] = 0;

    //依次插入n-1个节点
    for(int t=1;t<n;++t){
        //先找不在生成树中的最近的节点
        int min_value = INF;
        int min_index = 0;
        for(int i=0;i<n;++i){
            if(lowcost[i] && lowcost[i] < min_value){
                min_value = lowcost[i];
                min_index = i;
            }
        }

        ans+=lowcost[min_index]; // 累加树的权值
        
        lowcost[min_index] = 0;  // 更新生成树

        //开始更新lowcost
        for(int i=0;i<n;++i){
            if(lowcost[i]){ 
                lowcost[i] = min(map[min_index][i], lowcost[i]); 
            }
        }
    }

    return ans;
}

int main(){
    cin>>n>>m;
    for(int i=0;i<n;++i)
        for(int j=0;j<n;++j)
            map[i][j] = INF;

    int x,y,z;
    for(int i=0;i<m;++i){
        cin>>x>>y>>z;
        map[x-1][y-1] = min(z, map[x-1][y-1]);
        map[y-1][x-1] = map[x-1][y-1];
    }
    
    int ans = prim(n);

    for(int i=0;i<n;++i){
        if(lowcost[i]){
            cout<<"bad graph"<<endl;   //不连通
            return 0;
        }
    }

    cout<<ans<<endl;
    return 0;
}